package com.jiyun.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiyun.client.CapacityClient;
import com.jiyun.entity.Capacity;
import com.jiyun.entity.WangpanFile;
import com.jiyun.pojo.MyResult;
import com.jiyun.service.IWangpanFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  控制层
 * </p>
 *
 * @author 聪哥哥
 * @since 2023-04-23
 */
@RestController
@RequestMapping("/wangpan-file")
public class WangpanFileController {

    @Autowired
    IWangpanFileService wangpanFileService;


    @Autowired
    CapacityClient capacityClient;

    @RequestMapping("addDir")
    public void addDir(@RequestBody WangpanFile wangpanFile){
        //需要校验名称重复
        wangpanFile.setCreateTime(LocalDateTime.now());
        wangpanFileService.save(wangpanFile);
    }
    /**
     * 添加接口
     */
    @RequestMapping("/add")
    public void addWangpanFile(@RequestBody WangpanFile wangpanFile){
        //校验文件名是否重复
        String name = wangpanFile.getName().substring(0, wangpanFile.getName().lastIndexOf("."));
        LambdaQueryWrapper<WangpanFile> wangpanFileLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wangpanFileLambdaQueryWrapper.eq(WangpanFile::getPid,wangpanFile.getPid());
        wangpanFileLambdaQueryWrapper.like(WangpanFile::getName,name);
        wangpanFileLambdaQueryWrapper.orderByDesc(WangpanFile::getCreateTime);
        wangpanFileLambdaQueryWrapper.last(" limit 1");
        WangpanFile one = wangpanFileService.getOne(wangpanFileLambdaQueryWrapper);
        if (one!=null) {
            String nameDB = one.getName().substring(0,one.getName().lastIndexOf("."));
            if (nameDB.endsWith(")")) {
                String num = nameDB.substring(nameDB.lastIndexOf("(")+1,nameDB.lastIndexOf(")"));
                name = name +"("+(Integer.parseInt(num)+1)+")";
            }else{
                name = name +"(1)";
            }
            wangpanFile.setName(name+"."+wangpanFile.getSuffix());
        }
        wangpanFile.setCreateTime(LocalDateTime.now());
        wangpanFileService.save(wangpanFile);
        //更新网盘容量，已使用的加上，剩余的减去
        Object capacityObj = capacityClient.findByUid(wangpanFile.getUid()).getData();//linkedHashMap
        Capacity capacity = JSONObject.parseObject(JSONObject.toJSONString(capacityObj),Capacity.class);
        capacity.setCurrentCapacity(capacity.getCurrentCapacity()+wangpanFile.getFilesize());//用量增加
        capacity.setLastCapacity(capacity.getLastCapacity()-wangpanFile.getFilesize());//余量减少
        capacityClient.updateCapacity(capacity);

        //更新文件夹大小
        /**
         * 1、不更新根目录，不更新pid是-1的目录
         * 2、级联更新所有上级
         */

        updateParentFilesize(wangpanFile.getPid(),wangpanFile.getFilesize());
    }

    //添加时新增文件夹大小
    public void updateParentFilesize(Integer pid,Long toAddFileSize){
        if (pid!=-1){
            //更新上级
            WangpanFile parent = wangpanFileService.getById(pid);
            parent.setFilesize(parent.getFilesize()+toAddFileSize);
            wangpanFileService.updateById(parent);
            updateParentFilesize(parent.getPid(),toAddFileSize);
        }
    }

    public void updateParentFilesize4Jian(Integer pid,Long toJianFileSize){
        if (pid!=-1){
            //更新上级
            WangpanFile parent = wangpanFileService.getById(pid);
            parent.setFilesize(parent.getFilesize()-toJianFileSize);
            wangpanFileService.updateById(parent);
            updateParentFilesize4Jian(parent.getPid(),toJianFileSize);
        }
    }


    @RequestMapping("moveFile")
    public MyResult moveFile(String fids,Integer toPid){
        for (String fid : fids.split(",")) {
            /**
             * 把当前fid文件的pid改成toPid
             */
            WangpanFile wangpanFile = wangpanFileService.getById(fid);
            Integer oldPid = wangpanFile.getPid();
            //做名称重复校验

            //校验文件名是否重复
            String name = wangpanFile.getName().substring(0, wangpanFile.getName().lastIndexOf("."));
            LambdaQueryWrapper<WangpanFile> wangpanFileLambdaQueryWrapper = new LambdaQueryWrapper<>();
            wangpanFileLambdaQueryWrapper.eq(WangpanFile::getPid,toPid);
            wangpanFileLambdaQueryWrapper.like(WangpanFile::getName,name);
            wangpanFileLambdaQueryWrapper.orderByDesc(WangpanFile::getCreateTime);
            wangpanFileLambdaQueryWrapper.last(" limit 1");
            WangpanFile one = wangpanFileService.getOne(wangpanFileLambdaQueryWrapper);
            if (one!=null) {
                String nameDB = one.getName().substring(0,one.getName().lastIndexOf("."));
                if (nameDB.endsWith(")")) {
                    String num = nameDB.substring(nameDB.lastIndexOf("(")+1,nameDB.lastIndexOf(")"));
                    name = name +"("+(Integer.parseInt(num)+1)+")";
                }else{
                    name = name +"(1)";
                }
                wangpanFile.setName(name+"."+wangpanFile.getSuffix());
            }

            wangpanFile.setPid(toPid);
            wangpanFileService.updateById(wangpanFile);


            /**
             * toPid  加上大小
             */
            updateParentFilesize(toPid,wangpanFile.getFilesize());
            /**
             * 原来的pid  减去大小
             */
            updateParentFilesize4Jian(oldPid,wangpanFile.getFilesize());
        }
        return MyResult.OK();

    }


    /**
     * 修改接口
     */
    @RequestMapping("/update")
    public MyResult updateWangpanFile(@RequestBody WangpanFile wangpanFile){


        LambdaQueryWrapper<WangpanFile> wangpanFileLambdaQueryWrapper = new LambdaQueryWrapper<>();

        wangpanFileLambdaQueryWrapper.eq(WangpanFile::getName,wangpanFile.getName());
        wangpanFileLambdaQueryWrapper.eq(WangpanFile::getPid,wangpanFile.getPid());
        wangpanFileLambdaQueryWrapper.ne(WangpanFile::getId,wangpanFile.getId());

        if (wangpanFileService.count(wangpanFileLambdaQueryWrapper)>0) {
            return MyResult.ERROR("文件名重复");
        }


        wangpanFileService.updateById(wangpanFile);
        return MyResult.OK();
    }

    /**
     * 单个删除接口
     */
    @RequestMapping("/deleteOne")
    public void deleteOne(@RequestParam Integer id){
        wangpanFileService.removeById(id);
    }

    /**
     * 批量删除接口
     * 前台ajax参数ids传入示例：1,2,3  (英文逗号分隔的字符串)
     */
    @RequestMapping("/deleteBatch")
    public void deleteBatch(@RequestParam List<Integer> ids){
        /**
         * 1、级联删除所有子内容
         * 2、更新父级文件夹容量
         */

        for (Integer id : ids) {
            WangpanFile wangpanFile = wangpanFileService.getById(id);
            if (wangpanFile.getType()==1) {
                //更新容量
                updateParentFilesize4Jian(wangpanFile.getPid(),wangpanFile.getFilesize());

                /**
                 * 1、把自己的id作为pid，查询下级
                 *      如果有下级
                 *  递归删除
                 *
                  */
                delSonDir(wangpanFile);
            }else{
                updateParentFilesize4Jian(wangpanFile.getPid(),wangpanFile.getFilesize());
                wangpanFileService.removeById(id);
            }

        }
    }


    //文件夹
    public void delSonDir(WangpanFile file){
        LambdaQueryWrapper<WangpanFile> wangpanFileLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wangpanFileLambdaQueryWrapper.eq(WangpanFile::getPid,file.getId());
        List<WangpanFile> sonlist = wangpanFileService.list(wangpanFileLambdaQueryWrapper);
        if(CollectionUtils.isNotEmpty(sonlist)){
            for (WangpanFile wangpanFile : sonlist) {
                if(wangpanFile.getType()==1){//子级文件夹
                    delSonDir(wangpanFile);
                }else{
                    wangpanFileService.removeById(wangpanFile.getId());
                }
            }
        }
        wangpanFileService.removeById(file.getId());//删除完子级之后，把自己也删掉
    }

    /**
     * 根据id查询实体接口
     */
    @RequestMapping("/findById")
    public WangpanFile findById(@RequestParam Integer id){
        return wangpanFileService.getById(id);
    }

    /**
     * 查询所有接口
     */
    @RequestMapping("/findAll")
    public List<WangpanFile> findAll(){
        return wangpanFileService.list();
    }

    /**
     * 分页查询接口
     * 重要提示：启用分页功能必须在配置类中添加mybatis-plus分页的拦截器
     * 重要提示：启用分页功能必须在配置类中添加mybatis-plus分页的拦截器
     * 重要提示：启用分页功能必须在配置类中添加mybatis-plus分页的拦截器
     */
    @RequestMapping("/findPage")
    public Page<WangpanFile> findPage(@RequestParam Integer page,@RequestParam Integer pageSize){
        Page<WangpanFile> wangpanFilePage = new Page<>(page, pageSize);
        return wangpanFileService.page(wangpanFilePage);
    }

    @RequestMapping("findFileListByUid")
    public MyResult findFileListByUid(@RequestParam Integer uid,@RequestParam Integer pid,Integer type){
        LambdaQueryWrapper<WangpanFile> wangpanFileLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wangpanFileLambdaQueryWrapper.eq(WangpanFile::getUid,uid);
        wangpanFileLambdaQueryWrapper.eq(WangpanFile::getPid,pid);
        wangpanFileLambdaQueryWrapper.eq(type!=null,WangpanFile::getType,type);
        wangpanFileLambdaQueryWrapper.orderByAsc(WangpanFile::getType);//根据类型正序排列
        return MyResult.OK(wangpanFileService.list(wangpanFileLambdaQueryWrapper));
    }

    @Value("${com.jiyun.fileuploadPath}")
    String uploadPath;

    @GetMapping("/readtxt")
    public void readtxt(String name, HttpServletResponse response) throws IOException {
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        StringBuffer stringBuffer = new StringBuffer();
        BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(uploadPath + name)));
        String line = null;
        while ((line=bufferedReader.readLine())!=null){
            stringBuffer.append(line+"\n");
        }
        response.getWriter().write(stringBuffer.toString());
    }

    @RequestMapping("upload")
    public MyResult upload(MultipartFile file) throws Exception{

        //先校验这个文件是否上传过
        String uploadFileMd5 = getUploadFileMd5(file);

        LambdaQueryWrapper<WangpanFile> wangpanFileLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wangpanFileLambdaQueryWrapper.eq(WangpanFile::getMd5str,uploadFileMd5);

        List<WangpanFile> listFile = wangpanFileService.list(wangpanFileLambdaQueryWrapper);
        WangpanFile one = CollectionUtils.isEmpty(listFile)?null:listFile.get(0);

        HashMap hashMap = new HashMap();
        hashMap.put("md5",uploadFileMd5);

        if(one!=null){
            hashMap.put("url",one.getUrl());
            return MyResult.OK(hashMap);
        }
        String filename = UUID.randomUUID().toString()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        File file1 = new File(uploadPath + filename);
        file.transferTo(file1);

        hashMap.put("url",filename);
        return MyResult.OK(hashMap);

    }

    /**
     * 获取文件的MD5值
     * @param file
     * @return
     */
    public String getUploadFileMd5(MultipartFile file){
        try {
            byte[] uploadBytes = file.getBytes();
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] digest = md5.digest(uploadBytes);
            String hashString = new BigInteger(1, digest).toString(16);
            return hashString;

        } catch (Exception e) {
            System.out.println("获取文件md5失败");
        }
        return null;
    }

}
